﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using server_socket.Protocol;
using ProtoBuf;
using System.IO;

namespace server_socket
{
    class Program
    {
        private static Socket selfSocket = null;
        private const string ADDRESS = "192.168.0.117";
        private const int PORT = 4123;
        private const int CACHE_SIZE = 1024;
        private const int LISTEN = 10;

        static void Main(string[] args)
        {
            selfSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint end_point = new IPEndPoint(IPAddress.Parse(ADDRESS), PORT);
            selfSocket.Bind(end_point);
            selfSocket.Listen(LISTEN);

            Thread thread = new Thread(Wait);
            thread.IsBackground = true;
            thread.Start();

            Console.WriteLine("start listen on {0}:{1} ......", ADDRESS, PORT);
            Console.ReadKey();
            Console.WriteLine("stop listen ...");
        }

        private static void Wait()
        {
            Socket client = null;

            while (true)
            {
                try
                {
                    client = selfSocket.Accept();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("client error : {0}", ex.StackTrace);
                    break;
                }

                IPEndPoint client_point = client.RemoteEndPoint as IPEndPoint;
                IPAddress client_ip = client_point.Address;
                int client_port = client_point.Port;

                Console.WriteLine("connect {0} successful!", client_point.ToString());

                ParameterizedThreadStart parameterizedThreadStart = new ParameterizedThreadStart(RecvClient);
                Thread thread = new Thread(parameterizedThreadStart);
                thread.IsBackground = true;
                thread.Start(client);
            }
        }

        private static void RecvClient(object obj)
        {
            Socket client = obj as Socket;

            while (true)
            {
                byte[] msgCache = new byte[CACHE_SIZE * CACHE_SIZE];

                try
                {
                    int length = client.Receive(msgCache);

                    //Console.WriteLine("recive client message : {0}", Encoding.UTF8.GetString(msgCache, 0, length));

                    MemoryStream ms = new MemoryStream(msgCache, 0, length);
                    NetModelProtocol protocol = Serializer.Deserialize<NetModelProtocol>(ms);
                    Console.WriteLine("recive message : {0}", protocol.Message);

                    client.Send(Encoding.UTF8.GetBytes("recive client message in " + System.DateTime.Now.ToString("yyyyMMddhhmmss")));
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Source : {0}, StackTrace : {1}, Message : {2}", ex.Source, ex.StackTrace, ex.Message);
                    Console.WriteLine("client {0} is disconnect!", client.RemoteEndPoint);
                    client.Close();
                    client = null;

                    break;
                }
            }
        }
    }
}
